// 练习01
class Compile {
  constructor(el, vm) {
    this.$el = document.querySelector(el)
    this.$vm = vm
    this.$fragment = this.node2Fragment(this.$el)
    this.compile(this.$fragment)
    this.$el.appendChild(this.$fragment)
  }
  node2Fragment(node) {
    const fragment = document.createDocumentFragment()
    let child
    while (child = node.firstChild) {
      fragment.appendChild(child)
    }
    return fragment
  }
  isInter(node) {
    return node.nodeType === 3 && /\{\{(.*)\}\}/.test(node.textContent)
  }
  update(node, exp, dir) {
    const updator = this[dir + 'Updator']
    updator && updator(node, this.$vm[exp]) // 设置初始值

    // 给每个data里的字段加上监听器
    new Watcher(this.$vm, exp, function (value) {
      updator && updator(node, value)
    })
  }
  textUpdator(node, value) {
    node.textContent = value // 更新html里的{{}}里的内容
  }
  text(node, exp, dir) {
    this.update(node, exp, dir)
  }

  compile(fragment) {
    const childNodes = fragment.childNodes
    Array.from(childNodes).forEach(node => {
      if (node.nodeType === 1) {
        this.compileElement(node)
        console.log('编译标签', node.tagName);
      } else if (this.isInter(node)) {
        this.compileText(node)
        console.log('编译插值表达式', node.textContent);
      }
      if (node.childNodes.length > 0) this.compile(node)
    })
  }
  compileText(node) {
    const exp = RegExp.$1
    this.update(node, exp, 'text')
  }
  compileElement(node) {
    Array.from(node.attributes).forEach(attr => {
      // k-xxx="yyyy"
      const attrName = attr.name // k-xxx
      const exp = attr.value // yyy
      if (attrName.indexOf('k-') === 0) {
        const dir = attrName.substring(2) // 取第2位至最后的字符
        this[dir] && this[dir](node, exp, dir)
      }
    })
  }

}